home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / nethack.lha / nethack-3.1 / src / polyself.c < prev    next >
C/C++ Source or Header  |  1993-01-05  |  24KB  |  924 lines

  1. /*    SCCS Id: @(#)polyself.c 3.1    92/11/24
  2. /*    Copyright (C) 1987, 1988, 1989 by Ken Arromdee */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. /* Polymorph self routine. */
  6.  
  7. #include "hack.h"
  8.  
  9. #ifdef OVLB
  10. #ifdef POLYSELF
  11. static void NDECL(polyman);
  12. static void NDECL(break_armor);
  13. static void FDECL(drop_weapon,(int));
  14. static void NDECL(skinback);
  15. static void NDECL(uunstick);
  16. static int FDECL(armor_to_dragon,(int));
  17.  
  18. /* make a (new) human out of the player */
  19. static void
  20. polyman()
  21. {
  22.     boolean sticky = sticks(uasmon) && u.ustuck && !u.uswallow;
  23.  
  24.     if (u.umonnum != -1) {
  25.         u.acurr = u.macurr;    /* restore old attribs */
  26.         u.amax = u.mamax;
  27.         u.umonnum = -1;
  28.         flags.female = u.mfemale;
  29.     }
  30.     u.usym = S_HUMAN;
  31.     set_uasmon();
  32.  
  33.     u.mh = u.mhmax = 0;
  34.     u.mtimedone = 0;
  35.     skinback();
  36.     u.uundetected = 0;
  37.     newsym(u.ux,u.uy);
  38.  
  39.     if (sticky) uunstick();
  40.     find_ac();
  41.     if(!Levitation && !u.ustuck &&
  42.        (is_pool(u.ux,u.uy) || is_lava(u.ux,u.uy)))
  43.         spoteffects();
  44. }
  45. #endif /* POLYSELF */
  46.  
  47. void
  48. change_sex()
  49. {
  50.     flags.female = !flags.female;
  51.     max_rank_sz();
  52.     if (pl_character[0] == 'P')
  53.         Strcpy(pl_character+6, flags.female ? "ess" : "");
  54.     if (pl_character[0] == 'C')
  55.         Strcpy(pl_character+4, flags.female ? "woman" : "man");
  56. }
  57.  
  58. void
  59. newman()
  60. {
  61.     int tmp, tmp2;
  62.  
  63.     if (!rn2(10)) change_sex();
  64.  
  65.     tmp = u.uhpmax;
  66.     tmp2 = u.ulevel;
  67.     u.ulevel = u.ulevel-2+rn2(5);
  68.     if (u.ulevel > 127 || u.ulevel == 0) u.ulevel = 1;
  69.     if (u.ulevel > MAXULEV) u.ulevel = MAXULEV;
  70.  
  71.     adjabil(tmp2, (int)u.ulevel);
  72.  
  73.     /* random experience points for the new experience level */
  74.     u.uexp = rndexp();
  75. #ifndef LINT
  76.     u.uhpmax = (u.uhpmax-10)*(long)u.ulevel/tmp2 + 19 - rn2(19);
  77. #endif
  78. /* If it was u.uhpmax*u.ulevel/tmp+9-rn2(19), then a 1st level character
  79.    with 16 hp who polymorphed into a 3rd level one would have an average
  80.    of 48 hp.  */
  81. #ifdef LINT
  82.     u.uhp = u.uhp + tmp;
  83. #else
  84.     u.uhp = u.uhp * (long)u.uhpmax/tmp;
  85. #endif
  86.  
  87.     tmp = u.uenmax;
  88. #ifndef LINT
  89.     u.uenmax = u.uenmax * (long)u.ulevel/tmp2 + 9 - rn2(19);
  90. #endif
  91.     if (u.uenmax < 0) u.uenmax = 0;
  92. #ifndef LINT
  93.     u.uen = (tmp ? u.uen * (long)u.uenmax / tmp : u.uenmax);
  94. #endif
  95.  
  96.     redist_attr();
  97.     u.uhunger = rn1(500,500);
  98.     newuhs(FALSE);
  99.     Sick = 0;
  100.     Stoned = 0;
  101.     if (u.uhp <= 0 || u.uhpmax <= 0) {
  102. #ifdef POLYSELF
  103.         if(Polymorph_control) {
  104.             if (u.uhp <= 0) u.uhp = 1;
  105.             if (u.uhpmax <= 0) u.uhpmax = 1;
  106.         } else {
  107. #endif
  108.             Your("new form doesn't seem healthy enough to survive.");
  109.             killer_format = KILLED_BY_AN;
  110.             killer="unsuccessful polymorph";
  111.             done(DIED);
  112.             pline("Revived, you are in just as bad a shape as before.");
  113.             done(DIED);
  114. #ifdef POLYSELF
  115.         }
  116. #endif
  117.     }
  118. #ifdef POLYSELF
  119.     polyman();
  120. #endif
  121.     You("feel like a new %sman!", flags.female ? "wo" : "");
  122.     flags.botl = 1;
  123.     (void) encumber_msg();
  124. }
  125.  
  126. #ifdef POLYSELF
  127. void
  128. polyself()
  129. {
  130.     char buf[BUFSZ];
  131.     int mntmp = -1;
  132.     int tries=0;
  133.     boolean draconian = (uarm &&
  134.                 uarm->otyp >= GRAY_DRAGON_SCALE_MAIL &&
  135.                 uarm->otyp <= YELLOW_DRAGON_SCALES);
  136.  
  137.     boolean iswere = (u.ulycn > -1 || is_were(uasmon));
  138.     boolean isvamp = (u.usym == S_VAMPIRE || u.umonnum == PM_VAMPIRE_BAT);
  139.  
  140.     if(!Polymorph_control && !draconian && !iswere && !isvamp) {
  141.         if (rn2(20) > ACURR(A_CON)) {
  142.         You(shudder_for_moment);
  143.         losehp(rn2(30),"system shock", KILLED_BY_AN);
  144.         exercise(A_CON, FALSE);
  145.         return;
  146.         }
  147.     }
  148.  
  149.     if (Polymorph_control) {
  150.         do {
  151.             getlin("Become what kind of monster? [type the name]",
  152.                 buf);
  153.             mntmp = name_to_mon(buf);
  154.             if (mntmp < 0)
  155.                 pline("I've never heard of such monsters.");
  156.             /* Note:  humans are illegal as monsters, but an
  157.              * illegal monster forces newman(), which is what we
  158.              * want if they specified a human.... */
  159.             else if (!polyok(&mons[mntmp]) &&
  160.                 ((pl_character[0] == 'E') ? !is_elf(&mons[mntmp])
  161.                         : !is_human(&mons[mntmp])) )
  162.                 You("cannot polymorph into that.");
  163.             else break;
  164.         } while(++tries < 5);
  165.         if (tries==5) pline(thats_enough_tries);
  166.         /* allow skin merging, even when polymorph is controlled */
  167.         if (draconian &&
  168.             (mntmp == armor_to_dragon(uarm->otyp) || tries == 5))
  169.             goto do_merge;
  170.     } else if (draconian || iswere || isvamp) {
  171.         /* special changes that don't require polyok() */
  172.         if (draconian) {
  173.             do_merge:
  174.             mntmp = armor_to_dragon(uarm->otyp);
  175.             if (!(mons[mntmp].geno & G_GENOD)) {
  176.                 /* allow G_EXTINCT */
  177.                 You("merge with your scaly armor.");
  178.                 uskin = uarm;
  179.                 uarm = (struct obj *)0;
  180.             }
  181.         } else if (iswere) {
  182.             if (is_were(uasmon))
  183.                 mntmp = PM_HUMAN; /* Illegal; force newman() */
  184.             else
  185.                 mntmp = u.ulycn;
  186.         } else {
  187.             if (u.usym == S_VAMPIRE)
  188.                 mntmp = PM_VAMPIRE_BAT;
  189.             else
  190.                 mntmp = PM_VAMPIRE;
  191.         }
  192.         if (polymon(mntmp))
  193.             return;
  194.     }
  195.  
  196.     if (mntmp < 0) {
  197.         tries = 0;
  198.         do {
  199.             mntmp = rn2(PM_ARCHEOLOGIST);
  200.             /* All valid monsters are from 0 to PM_ARCHEOLOGIST-1 */
  201.         } while(!polyok(&mons[mntmp]) && tries++ < 200);
  202.     }
  203.  
  204.     /* The below polyok() fails either if everything is genocided, or if
  205.      * we deliberately chose something illegal to force newman().
  206.      */
  207.     if (!polyok(&mons[mntmp]) || !rn2(5))
  208.         newman();
  209.     else if(!polymon(mntmp)) return;
  210.  
  211.     if (!uarmg) selftouch("No longer petrify-resistant, you");
  212. }
  213.  
  214. /* (try to) make a mntmp monster out of the player */
  215. int
  216. polymon(mntmp)    /* returns 1 if polymorph successful */
  217. int    mntmp;
  218. {
  219.     boolean sticky = sticks(uasmon) && u.ustuck && !u.uswallow;
  220.     boolean dochange = FALSE;
  221.     int    tmp;
  222.  
  223.     if (mons[mntmp].geno & G_GENOD) {    /* allow G_EXTINCT */
  224.         You("feel rather %s-ish.",mons[mntmp].mname);
  225.         exercise(A_WIS, TRUE);
  226.         return(0);
  227.     }
  228.  
  229.     if (u.umonnum == -1) {
  230.         /* Human to monster; save human stats */
  231.         u.macurr = u.acurr;
  232.         u.mamax = u.amax;
  233.         u.mfemale = flags.female;
  234.     } else {
  235.         /* Monster to monster; restore human stats, to be
  236.          * immediately changed to provide stats for the new monster
  237.          */
  238.         u.acurr = u.macurr;
  239.         u.amax = u.mamax;
  240.         flags.female = u.mfemale;
  241.     }
  242.  
  243.     if (is_male(&mons[mntmp])) {
  244.         if(flags.female) dochange = TRUE;
  245.     } else if (is_female(&mons[mntmp])) {
  246.         if(!flags.female) dochange = TRUE;
  247.     } else if (!is_neuter(&mons[mntmp])) {
  248.         if(!rn2(10)) dochange = TRUE;
  249.     }
  250.     if (dochange) {
  251.         flags.female = !flags.female;
  252.         You("%s %s %s!",
  253.             (u.umonnum != mntmp) ? "turn into a" : "feel like a new",
  254.             flags.female ? "female" : "male",
  255.             mons[mntmp].mname);
  256.     } else {
  257.         if (u.umonnum != mntmp)
  258.             You("turn into %s!", an(mons[mntmp].mname));
  259.         else
  260.             You("feel like a new %s!", mons[mntmp].mname);
  261.     }
  262.  
  263.     u.umonnum = mntmp;
  264.     u.usym = mons[mntmp].mlet;
  265.     set_uasmon();
  266.  
  267.     /* New stats for monster, to last only as long as polymorphed.
  268.      * Currently only strength gets changed.
  269.      */
  270.     if(strongmonst(&mons[mntmp])) ABASE(A_STR) = AMAX(A_STR) = 118;
  271.  
  272.     if (resists_ston(uasmon) && Stoned) { /* parnes@eniac.seas.upenn.edu */
  273.         Stoned = 0;
  274.         You("no longer seem to be petrifying.");
  275.     }
  276.     if (u.usym == S_FUNGUS && Sick) {
  277.         Sick = 0;
  278.         You("no longer feel sick.");
  279.     }
  280.  
  281.     if (u.usym == S_DRAGON && mntmp >= PM_GRAY_DRAGON)
  282.         u.mhmax = 8 * mons[mntmp].mlevel;
  283.     else if (is_golem(uasmon)) u.mhmax = golemhp(mntmp);
  284.     else {
  285.         /*
  286.         tmp = adj_lev(&mons[mntmp]);
  287.          * We can't do this, since there's no such thing as an
  288.          * "experience level of you as a monster" for a polymorphed
  289.          * character.
  290.          */
  291.         tmp = mons[mntmp].mlevel;
  292.         if (!tmp) u.mhmax = rnd(4);
  293.         else u.mhmax = d(tmp, 8);
  294.     }
  295.     u.mh = u.mhmax;
  296.  
  297.     u.mtimedone = rn1(500, 500);
  298.     if (u.ulevel < mons[mntmp].mlevel)
  299.     /* Low level characters can't become high level monsters for long */
  300. #ifdef DUMB
  301.         {
  302.         /* DRS/NS 2.2.6 messes up -- Peter Kendell */
  303.             int    mtd = u.mtimedone,
  304.                 ulv = u.ulevel,
  305.                 mlv = mons[mntmp].mlevel;
  306.  
  307.             u.mtimedone = mtd * ulv / mlv;
  308.         }
  309. #else
  310.         u.mtimedone = u.mtimedone * u.ulevel / mons[mntmp].mlevel;
  311. #endif
  312.  
  313.     if (uskin && mntmp != armor_to_dragon(uskin->otyp))
  314.         skinback();
  315.     break_armor();
  316.     drop_weapon(1);
  317.     if (hides_under(uasmon))
  318.         u.uundetected = OBJ_AT(u.ux, u.uy);
  319.     else
  320.         u.uundetected = 0;
  321.     newsym(u.ux,u.uy);        /* Change symbol */
  322.  
  323.     if (!sticky && !u.uswallow && u.ustuck && sticks(uasmon)) u.ustuck = 0;
  324.     else if (sticky && !sticks(uasmon)) uunstick();
  325.  
  326.     if (flags.verbose) {
  327.         static const char use_thec[] = "Use the command #%s to %s.";
  328.         static const char monsterc[] = "monster";
  329.         if (can_breathe(uasmon))
  330.         pline(use_thec,monsterc,"use your breath weapon");
  331.         if (attacktype(uasmon, AT_SPIT))
  332.         pline(use_thec,monsterc,"spit venom");
  333.         if (u.usym == S_NYMPH)
  334.         pline(use_thec,monsterc,"remove an iron ball");
  335.         if (u.usym == S_UMBER)
  336.         pline(use_thec,monsterc,"confuse monsters");
  337.         if (is_hider(uasmon))
  338.         pline(use_thec,monsterc,"hide");
  339.         if (is_were(uasmon))
  340.         pline(use_thec,monsterc,"summon help");
  341.         if (webmaker(uasmon))
  342.         pline(use_thec,monsterc,"spin a web");
  343.         if (u.umonnum == PM_GREMLIN)
  344.         pline(use_thec,monsterc,"multiply in a fountain");
  345.         if (u.usym == S_UNICORN)
  346.         pline(use_thec,monsterc,"use your horn");
  347.         if (u.umonnum == PM_MIND_FLAYER)
  348.         pline(use_thec,monsterc,"for a mental blast");
  349.         if (uasmon->msound == MS_SHRIEK) /* worthless, actually */
  350.         pline(use_thec,monsterc,"shriek");
  351.         if ((lays_eggs(uasmon) || u.umonnum==PM_QUEEN_BEE) && flags.female)
  352.         pline(use_thec,"sit","lay an egg");
  353.     }
  354.     find_ac();
  355.     if((!Levitation && !u.ustuck && !is_flyer(uasmon) &&
  356.         (is_pool(u.ux,u.uy) || is_lava(u.ux,u.uy))) ||
  357.        (Underwater && !is_swimmer(uasmon)))
  358.         spoteffects();
  359.     if (passes_walls(uasmon) && u.utrap && u.utraptype == TT_INFLOOR) {
  360.         u.utrap = 0;
  361.         pline("The rock seems to no longer trap you.");
  362.     }
  363.     flags.botl = 1;
  364.     vision_full_recalc = 1;
  365.     exercise(A_CON, FALSE);
  366.     exercise(A_WIS, TRUE);
  367.     (void) encumber_msg();
  368.     return(1);
  369. }
  370.  
  371. static void
  372. break_armor()
  373. {
  374.      struct obj *otmp;
  375.  
  376.      if (breakarm(uasmon)) {
  377.     if (otmp = uarm) {
  378.         if (donning(otmp)) cancel_don();
  379.         You("break out of your armor!");
  380.         exercise(A_STR, FALSE);
  381.         (void) Armor_gone();
  382.         useup(otmp);
  383.     }
  384.     if (otmp = uarmc) {
  385.         if(otmp->oartifact) {
  386.         Your("cloak falls off!");
  387.         (void) Cloak_off();
  388.         dropx(otmp);
  389.         } else {
  390.         Your("cloak tears apart!");
  391.         (void) Cloak_off();
  392.         useup(otmp);
  393.         }
  394.     }
  395. #ifdef TOURIST
  396.     if (uarmu) {
  397.         Your("shirt rips to shreds!");
  398.         useup(uarmu);
  399.     }
  400. #endif
  401.      } else if (sliparm(uasmon)) {
  402.     if (otmp = uarm) {
  403.         if (donning(otmp)) cancel_don();
  404.         Your("armor falls around you!");
  405.         (void) Armor_gone();
  406.         dropx(otmp);
  407.     }
  408.     if (otmp = uarmc) {
  409.         if (is_whirly(uasmon))
  410.             Your("cloak falls, unsupported!");
  411.         else You("shrink out of your cloak!");
  412.         (void) Cloak_off();
  413.         dropx(otmp);
  414.     }
  415. #ifdef TOURIST
  416.     if (otmp = uarmu) {
  417.         if (is_whirly(uasmon))
  418.             You("seep right through your shirt!");
  419.         else You("become much too small for your shirt!");
  420.         setworn((struct obj *)0, otmp->owornmask & W_ARMU);
  421.         dropx(otmp);
  422.     }
  423. #endif
  424.      }
  425.      if (nohands(uasmon) || verysmall(uasmon)) {
  426.       if (otmp = uarmg) {
  427.            if (donning(otmp)) cancel_don();
  428.            /* Drop weapon along with gloves */
  429.            You("drop your gloves%s!", uwep ? " and weapon" : "");
  430.            drop_weapon(0);
  431.            (void) Gloves_off();
  432.            dropx(otmp);
  433.       }
  434.       if (otmp = uarms) {
  435.            You("can no longer hold your shield!");
  436.            (void) Shield_off();
  437.            dropx(otmp);
  438.       }
  439.       if (otmp = uarmh) {
  440.            if (donning(otmp)) cancel_don();
  441.            Your("helmet falls to the floor!");
  442.            (void) Helmet_off();
  443.            dropx(otmp);
  444.       }
  445.       if (otmp = uarmf) {
  446.            if (donning(otmp)) cancel_don();
  447.            if (is_whirly(uasmon))
  448.            Your("boots fall away!");
  449.            else Your("boots %s off your feet!",
  450.             verysmall(uasmon) ? "slide" : "are pushed");
  451.            (void) Boots_off();
  452.            dropx(otmp);
  453.       }
  454.      }
  455. }
  456.  
  457. static void
  458. drop_weapon(alone)
  459. int alone;
  460. {
  461.      struct obj *otmp;
  462.      if (otmp = uwep) {
  463.       /* !alone check below is currently superfluous but in the
  464.        * future it might not be so if there are monsters which cannot
  465.        * wear gloves but can wield weapons
  466.        */
  467.       if (!alone || cantwield(uasmon)) {
  468.            if (alone) You("find you must drop your weapon!");
  469.            uwepgone();
  470.            dropx(otmp);
  471.       }
  472.      }
  473. }
  474.  
  475. void
  476. rehumanize()
  477. {
  478.     polyman();
  479.     You("return to %sn form!", (pl_character[0] == 'E')? "elve" : "huma");
  480.  
  481.     if (u.uhp < 1)    done(DIED);
  482.     if (!uarmg) selftouch("No longer petrify-resistant, you");
  483.     nomul(0);
  484.  
  485.     flags.botl = 1;
  486.     vision_full_recalc = 1;
  487.     (void) encumber_msg();
  488. }
  489.  
  490. int
  491. dobreathe() {
  492.     if (Strangled) {
  493.         You("can't breathe.  Sorry.");
  494.         return(0);
  495.     }
  496.     if (!getdir(NULL)) return(0);
  497.     if (rn2(4))
  498.         You("produce a loud and noxious belch.");
  499.     else {
  500.         register struct attack *mattk;
  501.         register int i;
  502.  
  503.         for(i = 0; i < NATTK; i++) {
  504.         mattk = &(uasmon->mattk[i]);
  505.         if(mattk->aatyp == AT_BREA) break;
  506.         }
  507.         buzz((int) (20 + mattk->adtyp-1), (int)mattk->damn,
  508.         u.ux, u.uy, u.dx, u.dy);
  509.     }
  510.     return(1);
  511. }
  512.  
  513. int
  514. dospit() {
  515.     struct obj *otmp;
  516.  
  517.     if (!getdir(NULL)) return(0);
  518.     otmp = mksobj(u.umonnum==PM_COBRA ? BLINDING_VENOM : ACID_VENOM, TRUE, FALSE);
  519.     otmp->spe = 1; /* to indicate it's yours */
  520.     (void) throwit(otmp);
  521.     return(1);
  522. }
  523.  
  524. int
  525. doremove() {
  526.     if (!Punished) {
  527.         You("are not chained to anything!");
  528.         return(0);
  529.     }
  530.     unpunish();
  531.     return(1);
  532. }
  533.  
  534. int
  535. dospinweb()
  536. {
  537.     register struct trap *ttmp = t_at(u.ux,u.uy);
  538.  
  539.     if (Levitation || Is_airlevel(&u.uz)
  540.         || Underwater || Is_waterlevel(&u.uz)) {
  541.         You("must be on the ground to spin a web.");
  542.         return(0);
  543.     }
  544.     if (u.uswallow) {
  545.         You("release web fluid inside %s.", mon_nam(u.ustuck));
  546.         if (is_animal(u.ustuck->data)) {
  547.             expels(u.ustuck, u.ustuck->data, TRUE);
  548.             return(0);
  549.         }
  550.         if (is_whirly(u.ustuck->data)) {
  551.             int i;
  552.  
  553.             for (i = 0; i < NATTK; i++)
  554.                 if (u.ustuck->data->mattk[i].aatyp == AT_ENGL)
  555.                     break;
  556.             if (i == NATTK)
  557.                    impossible("Swallower has no engulfing attack?");
  558.             else {
  559.                 char sweep[30];
  560.  
  561.                 sweep[0] = '\0';
  562.                 switch(u.ustuck->data->mattk[i].adtyp) {
  563.                     case AD_FIRE:
  564.                         Strcpy(sweep, "ignites and ");
  565.                         break;
  566.                     case AD_ELEC:
  567.                         Strcpy(sweep, "fries and ");
  568.                         break;
  569.                     case AD_COLD:
  570.                         Strcpy(sweep,
  571.                               "freezes, shatters and ");
  572.                         break;
  573.                 }
  574.                 pline("The web %sis swept away!", sweep);
  575.             }
  576.             return(0);
  577.         }             /* default: a nasty jelly-like creature */
  578.         pline("The web dissolves into %s.", mon_nam(u.ustuck));
  579.         return(0);
  580.     }
  581.     if (u.utrap) {
  582.         You("cannot spin webs while stuck in a trap.");
  583.         return(0);
  584.     }
  585.     exercise(A_DEX, TRUE);
  586.     if (ttmp) switch (ttmp->ttyp) {
  587.         case PIT:
  588.         case SPIKED_PIT: You("spin a web, covering up the pit.");
  589.             deltrap(ttmp);
  590.             delallobj(u.ux, u.uy);
  591.             if (Invisible) newsym(u.ux, u.uy);
  592.             return(1);
  593.         case SQKY_BOARD: pline("The squeaky board is muffled.");
  594.             deltrap(ttmp);
  595.             if (Invisible) newsym(u.ux, u.uy);
  596.             return(1);
  597.         case TELEP_TRAP:
  598.         case LEVEL_TELEP:
  599.             Your("webbing vanishes!");
  600.             return(0);
  601.         case WEB: You("make the web thicker.");
  602.             return(1);
  603.         case TRAPDOOR:
  604.             You("web over the trap door.");
  605.             deltrap(ttmp);
  606.             if (Invisible) newsym(u.ux, u.uy);
  607.             return 1;
  608.         case ARROW_TRAP:
  609.         case DART_TRAP:
  610.         case BEAR_TRAP:
  611.         case LANDMINE:
  612.         case SLP_GAS_TRAP:
  613.         case RUST_TRAP:
  614.         case MAGIC_TRAP:
  615.         case ANTI_MAGIC:
  616.         case POLY_TRAP:
  617.             You("have triggered a trap!");
  618.             dotrap(ttmp);
  619.             return(1);
  620.         default:
  621.             impossible("Webbing over trap type %d?", ttmp->ttyp);
  622.             return(0);
  623.     }
  624.     ttmp = maketrap(u.ux, u.uy, WEB);
  625.     ttmp->tseen = 1;
  626.     if (Invisible) newsym(u.ux, u.uy);
  627.     return(1);
  628. }
  629.  
  630. int
  631. dosummon()
  632. {
  633.     You("call upon your brethren for help!");
  634.     exercise(A_WIS, TRUE);
  635.     if (!were_summon(uasmon,TRUE))
  636.         pline("But none arrive.");
  637.     return(1);
  638. }
  639.  
  640. int
  641. doconfuse()
  642. {
  643.     register struct monst *mtmp;
  644.     int looked = 0;
  645.     char qbuf[QBUFSZ];
  646.  
  647.     if (Blind) {
  648.         You("can't see anything to gaze at.");
  649.         return 0;
  650.     }
  651.     for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  652.         if (canseemon(mtmp)) {
  653.         looked = 1;
  654.         if (Invis && !perceives(mtmp->data))
  655.             pline("%s seems not to notice your gaze.", Monnam(mtmp));
  656.         else if (mtmp->minvis && !See_invisible)
  657.             You("can't see where to gaze at %s.", Monnam(mtmp));
  658.         else if (mtmp->m_ap_type == M_AP_FURNITURE
  659.             || mtmp->m_ap_type == M_AP_OBJECT)
  660.             continue;
  661.         else if (flags.safe_dog && !Confusion && !Hallucination
  662.           && mtmp->mtame) {
  663.             if (mtmp->mnamelth)
  664.             You("avoid gazing at %s.", NAME(mtmp));
  665.             else
  666.             You("avoid gazing at your %s.",
  667.                         mtmp->data->mname);
  668.         } else {
  669.             if (flags.confirm && mtmp->mpeaceful && !Confusion
  670.                             && !Hallucination) {
  671.             Sprintf(qbuf, "Really confuse %s?", mon_nam(mtmp));
  672.             if (yn(qbuf) != 'y') continue;
  673.             setmangry(mtmp);
  674.             }
  675.             if (!mtmp->mcanmove || mtmp->mstun || mtmp->msleep ||
  676.                     !mtmp->mcansee || !haseyes(mtmp->data))
  677.             continue;
  678.             if (!mtmp->mconf)
  679.             Your("gaze confuses %s!", mon_nam(mtmp));
  680.             else
  681.             pline("%s is getting more and more confused.",
  682.                             Monnam(mtmp));
  683.             mtmp->mconf = 1;
  684.             if ((mtmp->data==&mons[PM_FLOATING_EYE]) && !mtmp->mcan) {
  685.             You("are frozen by %s gaze!", 
  686.                              s_suffix(mon_nam(mtmp)));
  687.             nomul((u.ulevel > 6 || rn2(4)) ?
  688.                 -d((int)mtmp->m_lev+1,
  689.                     (int)mtmp->data->mattk[0].damd)
  690.                 : -200);
  691.             return 1;
  692.             }
  693.             if ((mtmp->data==&mons[PM_MEDUSA]) && !mtmp->mcan) {
  694.             pline("Gazing at the awake Medusa is not a very good idea.");
  695.             /* as if gazing at a sleeping anything is fruitful... */
  696.             You("turn to stone...");
  697.             done(STONING);
  698.             }
  699.         }
  700.         }
  701.     }
  702.     if (!looked) You("gaze at no place in particular.");
  703.     return 1;
  704. }
  705.  
  706. int
  707. dohide()
  708. {
  709.     if (u.uundetected || u.usym == S_MIMIC_DEF) {
  710.         You("are already hiding.");
  711.         return(0);
  712.     }
  713.     if (u.usym == S_MIMIC) {
  714.         u.usym = S_MIMIC_DEF;
  715.     } else {
  716.         u.uundetected = 1;
  717.     }
  718.     newsym(u.ux,u.uy);
  719.     return(1);
  720. }
  721.  
  722. int
  723. domindblast()
  724. {
  725.     struct monst *mtmp, *nmon;
  726.  
  727.     You("concentrate.");
  728.     if (rn2(3)) return 0;
  729.     pline("A wave of psychic energy pours out.");
  730.     for(mtmp=fmon; mtmp; mtmp = nmon) {
  731.         int u_sen;
  732.  
  733.         nmon = mtmp->nmon;
  734.         if (distu(mtmp->mx, mtmp->my) > BOLT_LIM * BOLT_LIM)
  735.             continue;
  736.         if(mtmp->mpeaceful)
  737.             continue;
  738.         u_sen = telepathic(mtmp->data) && !mtmp->mcansee;
  739.         if (u_sen || (telepathic(mtmp->data) && rn2(2)) || !rn2(10)) {
  740.             pline("You lock in on %s's %s.", mon_nam(mtmp),
  741.                 u_sen ? "telepathy" :
  742.                 telepathic(mtmp->data) ? "latent telepathy" :
  743.                 "mind");
  744.             mtmp->mhp -= rnd(15);
  745.             if (mtmp->mhp <= 0)
  746.                 killed(mtmp);
  747.         }
  748.     }
  749.     return 1;
  750. }
  751.  
  752. static void
  753. uunstick()
  754. {
  755.     pline("%s is no longer in your clutches.", Monnam(u.ustuck));
  756.     u.ustuck = 0;
  757. }
  758.  
  759. static void
  760. skinback()
  761. {
  762.     if (uskin) {
  763.         Your("skin returns to its original form.");
  764.         uarm = uskin;
  765.         uskin = (struct obj *)0;
  766.     }
  767. }
  768. #endif
  769.  
  770. #endif /* OVLB */
  771. #ifdef OVL1
  772. const char *
  773. body_part(part)
  774. int part;
  775. {
  776.     /* Note: it is assumed these will never be >22 characters long,
  777.      * plus the trailing null, after pluralizing (since sometimes a
  778.      * buffer is made a fixed size and must be able to hold it)
  779.      */
  780.     static const char NEARDATA *humanoid_parts[] = { "arm", "eye", "face", "finger",
  781.         "fingertip", "foot", "hand", "handed", "head", "leg",
  782.         "light headed", "neck", "spine", "toe" };
  783. #ifdef POLYSELF
  784.     static const char NEARDATA *jelly_parts[] = { "pseudopod", "dark spot", "front",
  785.         "pseudopod extension", "pseudopod extremity",
  786.         "pseudopod root", "grasp", "grasped", "cerebral area",
  787.         "lower pseudopod", "viscous", "middle", "surface",
  788.         "pseudopod extremity" },
  789.     NEARDATA *animal_parts[] = { "forelimb", "eye", "face", "foreclaw", "claw tip",
  790.         "rear claw", "foreclaw", "clawed", "head", "rear limb",
  791.         "light headed", "neck", "spine", "rear claw tip" },
  792.     NEARDATA *horse_parts[] = { "forelimb", "eye", "face", "forehoof", "hoof tip",
  793.         "rear hoof", "foreclaw", "hooved", "head", "rear limb",
  794.         "light headed", "neck", "backbone", "rear hoof tip" },
  795.     NEARDATA *sphere_parts[] = { "appendage", "optic nerve", "body", "tentacle",
  796.         "tentacle tip", "lower appendage", "tentacle", "tentacled",
  797.         "body", "lower tentacle", "rotational", "equator", "body",
  798.         "lower tentacle tip" },
  799.     NEARDATA *fungus_parts[] = { "mycelium", "visual area", "front", "hypha",
  800.         "hypha", "root", "strand", "stranded", "cap area",
  801.         "rhizome", "sporulated", "stalk", "root", "rhizome tip" },
  802.     NEARDATA *vortex_parts[] = { "region", "eye", "front", "minor current",
  803.         "minor current", "lower current", "swirl", "swirled",
  804.         "central core", "lower current", "addled", "center",
  805.         "currents", "edge" },
  806.     NEARDATA *snake_parts[] = { "vestigial limb", "eye", "face", "large scale",
  807.         "large scale tip", "rear region", "scale gap", "scale gapped",
  808.         "head", "rear region", "light headed", "neck", "length",
  809.         "rear scale" };
  810.  
  811.     if (humanoid(uasmon) && (part==ARM || part==FINGER || part==FINGERTIP
  812.         || part==HAND || part==HANDED)) return humanoid_parts[part];
  813.     if (u.usym==S_CENTAUR || u.usym==S_UNICORN) return horse_parts[part];
  814.     if (slithy(uasmon)) return snake_parts[part];
  815.     if (u.usym==S_EYE) return sphere_parts[part];
  816.     if (u.usym==S_JELLY || u.usym==S_PUDDING || u.usym==S_BLOB)
  817.         return jelly_parts[part];
  818.     if (u.usym==S_VORTEX || u.usym==S_ELEMENTAL) return vortex_parts[part];
  819.     if (u.usym==S_FUNGUS) return fungus_parts[part];
  820.     if (humanoid(uasmon)) return humanoid_parts[part];
  821.     return animal_parts[part];
  822. #else
  823.     return humanoid_parts[part];
  824. #endif
  825. }
  826.  
  827. #endif /* OVL1 */
  828. #ifdef OVL0
  829.  
  830. int
  831. poly_gender()
  832. {
  833. /* Returns gender of polymorphed player; 0/1=same meaning as flags.female,
  834.  * 2=none.
  835.  * Used in:
  836.  *    - Seduction by succubus/incubus
  837.  *    - Talking to nymphs (sounds.c)
  838.  * Not used in:
  839.  *    - Messages given by nymphs stealing armor (they can't steal from
  840.  *      incubi/succubi/nymphs, and nonhumanoids can't wear armor).
  841.  *    - Amulet of change (must refer to real gender no matter what
  842.  *      polymorphed into).
  843.  *    - Priest/Priestess, Caveman/Cavewoman (ditto)
  844.  *    - Polymorph self (only happens when human)
  845.  *    - Shopkeeper messages (since referred to as "creature" and not "sir"
  846.  *      or "lady" when polymorphed)
  847.  */
  848. #ifdef POLYSELF
  849.     if (!humanoid(uasmon)) return 2;
  850. #endif
  851.     return flags.female;
  852. }
  853.  
  854. #endif /* OVL0 */
  855. #ifdef OVLB
  856.  
  857. #if defined(POLYSELF)
  858. void
  859. ugolemeffects(damtype, dam)
  860. int damtype, dam;
  861. {
  862.     int heal = 0;
  863.     /* We won't bother with "slow"/"haste" since players do not
  864.      * have a monster-specific slow/haste so there is no way to
  865.      * restore the old velocity once they are back to human.
  866.      */
  867.     if (u.umonnum != PM_FLESH_GOLEM && u.umonnum != PM_IRON_GOLEM)
  868.         return;
  869.     switch (damtype) {
  870.         case AD_ELEC: if (u.umonnum == PM_IRON_GOLEM)
  871.                 heal = dam / 6; /* Approx 1 per die */
  872.             break;
  873.         case AD_FIRE: if (u.umonnum == PM_IRON_GOLEM)
  874.                 heal = dam;
  875.             break;
  876.     }
  877.     if (heal && (u.mh < u.mhmax)) {
  878.         u.mh += heal;
  879.         if (u.mh > u.mhmax) u.mh = u.mhmax;
  880.         flags.botl = 1;
  881.         pline("Strangely, you feel better than before.");
  882.         exercise(A_STR, TRUE);
  883.     }
  884. }
  885.  
  886. static int
  887. armor_to_dragon(atyp)
  888. int atyp;
  889. {
  890.     switch(atyp) {
  891.         case GRAY_DRAGON_SCALE_MAIL:
  892.         case GRAY_DRAGON_SCALES:
  893.         return PM_GRAY_DRAGON;
  894.         case RED_DRAGON_SCALE_MAIL:
  895.         case RED_DRAGON_SCALES:
  896.         return PM_RED_DRAGON;
  897.         case ORANGE_DRAGON_SCALE_MAIL:
  898.         case ORANGE_DRAGON_SCALES:
  899.         return PM_ORANGE_DRAGON;
  900.         case WHITE_DRAGON_SCALE_MAIL:
  901.         case WHITE_DRAGON_SCALES:
  902.         return PM_WHITE_DRAGON;
  903.         case BLACK_DRAGON_SCALE_MAIL:
  904.         case BLACK_DRAGON_SCALES:
  905.         return PM_BLACK_DRAGON;
  906.         case BLUE_DRAGON_SCALE_MAIL:
  907.         case BLUE_DRAGON_SCALES:
  908.         return PM_BLUE_DRAGON;
  909.         case GREEN_DRAGON_SCALE_MAIL:
  910.         case GREEN_DRAGON_SCALES:
  911.         return PM_GREEN_DRAGON;
  912.         case YELLOW_DRAGON_SCALE_MAIL:
  913.         case YELLOW_DRAGON_SCALES:
  914.         return PM_YELLOW_DRAGON;
  915.         default:
  916.         return -1;
  917.     }
  918. }
  919. #endif /* POLYSELF */
  920.  
  921. #endif /* OVLB */
  922.  
  923. /*polyself.c*/
  924.